package cn.datax.service.file.config;

import cn.datax.service.file.api.entity.FileEntity;
import cn.datax.service.file.properties.FileServerProperties;
import cn.datax.service.file.properties.MinioProperties;
import cn.datax.service.file.service.impl.FileServiceImpl;
import cn.datax.service.file.util.FileUtil;
import io.minio.*;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;

import static cn.datax.service.file.util.FileUtil.SINGLE_SLASH;

/**
 * Minio文件上传配置文件
 * @author houzb
 * @since 2023-05-23
 */
@Slf4j
@Configuration
@ConditionalOnProperty(name = "data.file-server.type", havingValue = "minio")
public class MinioServerConfig {
    private final Logger logger = LoggerFactory.getLogger(MinioServerConfig.class);

    @Autowired
    private FileServerProperties fileProperties;

    /**
     * minio文件存储client
     */
    @Bean
    public MinioClient minioClient() {
        MinioClient minioClient = null;
        MinioProperties minioProperties = fileProperties.getMinio();
        try {
            minioClient = MinioClient.builder()
                    .endpoint(minioProperties.getMinioUrl())
                    .credentials(minioProperties.getMinioName(), minioProperties.getMinioPass())
                    .build();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return minioClient;
    }

    @Service
    public class MinioServiceImpl extends FileServiceImpl {
        @Autowired
        private MinioClient minioClient;

        @Override
        protected String fileType() {
            return fileProperties.getType();
        }

        @Override
        protected void uploadFile(MultipartFile file, FileEntity fileEntity) {

            String fileUrl = "";
            String newBucket = fileProperties.getMinio().getBucketName();
            try {
                // 检查存储桶是否已经存在
                if(minioClient.bucketExists(BucketExistsArgs.builder().bucket(newBucket).build())) {
                    logger.info("Bucket already exists.");
                } else {
                    // 创建一个名为ota的存储桶
                    minioClient.makeBucket(MakeBucketArgs.builder().bucket(newBucket).build());
                    logger.info("create a new bucket.");
                }
                InputStream stream = file.getInputStream();
                // 获取文件名
                String orgName = file.getOriginalFilename();
                if("".equals(orgName)){
                    orgName=file.getName();
                }
                orgName = FileUtil.getFileName(orgName);
                String objectName = "/"
                        +( orgName.indexOf(".")==-1
                        ?orgName + "_" + System.currentTimeMillis()
                        :orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."))
                );

                // 使用putObject上传一个本地文件到存储桶中。
                if(objectName.startsWith(SINGLE_SLASH)){
                    objectName = objectName.substring(1);
                }
                PutObjectArgs objectArgs = PutObjectArgs.builder().object(objectName)
                        .bucket(newBucket)
                        .contentType("application/octet-stream")
                        .stream(stream,stream.available(),-1).build();
                minioClient.putObject(objectArgs);
                stream.close();
                fileEntity.setFilePath(fileProperties.getMinio().getMinioUrl()+newBucket+"/"+objectName);
            }catch (Exception e){
                log.error(e.getMessage(), e);
                e.printStackTrace();
            }

        }

        @Override
        protected void deleteFile(FileEntity fileEntity) {
            try {
                RemoveObjectArgs objectArgs = RemoveObjectArgs.builder().object(fileEntity.getFileName())
                        .bucket(fileProperties.getMinio().getMinioName()).build();
                minioClient.removeObject(objectArgs);
            }catch (Exception e){
                logger.error("文件删除失败" + e.getMessage());
            }
        }
    }

}
